package com.example.costumview.customview2;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.costumview.model.ChartDataResponseBean;
import com.example.costumview.model.DaolianBean;
import com.example.costumview.model.DataBean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ChartView extends View {

    //整个view缩放平移的操作矩阵
    private Matrix mMatrix;
    private Paint backGroundSquarePaint_big;
    private Paint backGroundSquarePaint_small;
    private Paint pointPaint;
    private Paint daolianTextPaint;
    private Paint mRulerLinePaint;
    private Paint mRulerTextPaint;
    private GestureDetector mGestureDetector;

    int xZengyi = 1;
    int yZengyi = 1;

    private float preScale = 1.0f;//之前的伸缩值
    private float curScale = 1.0f;//当前的伸缩值
    //缩放点坐标
    float scaleFousX = 0.0f;
    float scaleFousY = 0.0f;

    //上次平移距离
    float lastTranslateX = 0.0f;

    float lastTranslateY = 0.0f;

    //总平移距离
    int totalRulerTranslateX;
    //总平移距离
    int totalRulerTranlateY;

    private boolean isCanMove;
    //是否显示背景网格线
    boolean isShowBackGroundLine = true;

    //是否显示刻度尺
    boolean isShowRuler = false;

    //原始的12导联数据
    ArrayList<DaolianBean> originTotalDaolianList = new ArrayList<>();

    String[] totalDaolianTexts = {"I", "II", "III", "aVR", "aVL", "aVF", "V1", "V2", "V3", "V4", "V5", "V6"};

    //实际网络值加上简单计算返回的导联
    ArrayList<String> realtotalDaolianTexts = new ArrayList<>();

    //大方格边长
    float bigSpace = 80;
    //小方格边长
    float smallSpace = bigSpace / 5;
    //原始坐标的最大值最小值记录
    int minXPosition = 0;
    int minYPosition = 0;
    float minX = 0;
    float minY = 0;
    int maxXPosition = 0;
    int maxYPosition = 0;
    float maxX = 0;
    float maxY = 0;
    //画心电图是左侧要留出文字的位置,所以右移一下
    int leftMargin = (int) (bigSpace * 2);

    //经过增益变化后或显示隐藏某个导联的数据
    ArrayList<DaolianBean> totalDaolianList = new ArrayList<>();
    //上一次变换之后的点坐标. 这里拿到的就是最后画到上边的点坐标
    ArrayList<DataBean> lastPointList = new ArrayList<>();
    //原始数据点
    ArrayList<DataBean> pointList = new ArrayList<>();
    ArrayList<String> selectDaolianTexts = new ArrayList<>();
    float maxDaolianYDistance = bigSpace * 10;
    //显示的导联
    ArrayList<Integer> daolianSelectedList = new ArrayList<>();

    public ChartView(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        mMatrix = new Matrix();
        initPaint();
        initGestureDetector();
    }

    private void initGestureDetector() {
        //缩放监听
        ScaleGestureDetector mScaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.SimpleOnScaleGestureListener() {
            @Override
            public boolean onScaleBegin(@NonNull ScaleGestureDetector detector) {
                return super.onScaleBegin(detector);
            }

            @Override
            public boolean onScale(@NonNull ScaleGestureDetector detector) {
                return super.onScale(detector);
            }

            @Override
            public void onScaleEnd(@NonNull ScaleGestureDetector detector) {
                super.onScaleEnd(detector);
            }
        });
        //拖动监听
        mGestureDetector = new GestureDetector(getContext(), new GestureDetector.OnGestureListener() {
            @Override
            public boolean onDown(@NonNull MotionEvent e) {
                return false;
            }

            @Override
            public void onShowPress(@NonNull MotionEvent e) {

            }

            @Override
            public boolean onSingleTapUp(@NonNull MotionEvent e) {
                return false;
            }

            @Override
            public boolean onScroll(@NonNull MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) {
                return false;
            }

            @Override
            public void onLongPress(@NonNull MotionEvent e) {

            }

            @Override
            public boolean onFling(@NonNull MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) {
                return false;
            }
        });
    }

    private void initPaint() {
        //大网格线画笔
        backGroundSquarePaint_big = new Paint(Paint.ANTI_ALIAS_FLAG);
        backGroundSquarePaint_big.setColor(Color.parseColor("#434343"));
        backGroundSquarePaint_big.setStrokeWidth(2f);
        //抗锯齿
        backGroundSquarePaint_big.setAntiAlias(true);
        backGroundSquarePaint_big.setStyle(Paint.Style.FILL);

        //小网格线
        backGroundSquarePaint_small = new Paint(Paint.ANTI_ALIAS_FLAG);
        backGroundSquarePaint_small.setColor(Color.parseColor("#434343"));
        backGroundSquarePaint_small.setStrokeWidth(2f);
        //抗锯齿
        backGroundSquarePaint_small.setAntiAlias(true);
        backGroundSquarePaint_small.setStyle(Paint.Style.FILL);

        //折线图点的画笔
        pointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        pointPaint.setColor(Color.parseColor("#00C202"));
        pointPaint.setStrokeWidth(2f);
        //抗锯齿
        pointPaint.setAntiAlias(true);
        //不填充
        pointPaint.setStyle(Paint.Style.STROKE);

        //导联左端文字画笔
        daolianTextPaint = new Paint();
        daolianTextPaint.setColor(Color.parseColor("#FFFFFF"));
        daolianTextPaint.setAntiAlias(true);
        daolianTextPaint.setStyle(Paint.Style.FILL);
        daolianTextPaint.setStrokeWidth(1);
        daolianTextPaint.setTextSize(sp2px(11));

        initRulerPaint();
    }

    private void initRulerPaint() {
        mRulerLinePaint = new Paint();
        mRulerLinePaint.setColor(Color.parseColor("#FF0000"));
        mRulerLinePaint.setAntiAlias(true);//抗锯齿
        mRulerLinePaint.setStyle(Paint.Style.STROKE);
        mRulerLinePaint.setStrokeWidth(4);
        mRulerTextPaint = new Paint();
        mRulerTextPaint.setColor(Color.parseColor("#FF0000"));
        mRulerTextPaint.setAntiAlias(true);
        mRulerTextPaint.setStyle(Paint.Style.FILL);
        mRulerTextPaint.setStrokeWidth(1);
        mRulerTextPaint.setTextSize(sp2px(10));
    }

    public void setData(Map<String, ArrayList<Integer>> map, ChartDataResponseBean responseData) {
        originTotalDaolianList.clear();
        for (int i = 0; i < totalDaolianTexts.length; i++) {
            if (map.containsKey(totalDaolianTexts[i])) {
                realtotalDaolianTexts.add(totalDaolianTexts[i]);
            }
        }

        float perPointSpace = bigSpace * 5 / responseData.getTaskInfo().getSampleRate();
        for (int i = 0; i < totalDaolianTexts.length; i++) {
            DaolianBean daolianBean = new DaolianBean();
            ArrayList<Integer> list = map.get(totalDaolianTexts[i]);
            if (list != null) {
                float x = leftMargin;
                for (int i1 = 0; i1 < list.size(); i1++) {

                    daolianBean.getPointList().add(new DataBean(x, list.get(i1) * bigSpace * 2 / 1000));
                    x += perPointSpace;

                }
                originTotalDaolianList.add(daolianBean);
            }

        }
        //取反坐标轴
        jiaozhengZuobiaoxi();

        restore();
        calculateData();
        invalidate();

    }

    //计算数据,进行处理
    //主要是根据选择的显示导联,去除无用导联,并进行增益,最终合并入一个统一的大list,便于绘制和判断边界点.
    //核心思想:虽然绘制了多个导联,实际上我只是在绘制一个list中的所有点.
    //此方法耗时长,减少使用
    private void calculateData() {
        totalDaolianList.clear();
        pointList.clear();
        selectDaolianTexts.clear();
        List<DaolianBean> tempList = depCopyDaolian(originTotalDaolianList);

        float addY = 0;
        for (int i = 0; i < tempList.size(); i++) {
            if (daolianSelectedList.contains(i)) {
                selectDaolianTexts.add(realtotalDaolianTexts.get(i));
                float maxY = tempList.get(i).getPointList().get(0).y;
                float minY = tempList.get(i).getPointList().get(0).y;

                for (int i1 = 0; i1 < tempList.get(i).getPointList().size(); i1++) {
                    DataBean dataBean = tempList.get(i).getPointList().get(i1);
                    if (dataBean.y > maxY) {
                        maxY = dataBean.y;
                        tempList.get(i).maxYPosition = i1;
                    }

                    if (dataBean.y < minY) {
                        minY = dataBean.y;
                        tempList.get(i).minYPosition = i1;
                    }


                }
                //记录坐标差,为了计算基线
                tempList.get(i).prePosition0Y = tempList.get(i).getPointList().get(0).y;
                for (int i1 = 0; i1 < tempList.get(i).getPointList().size(); i1++) {
                    DataBean dataBean = tempList.get(i).getPointList().get(i1);
                    //加上之前的导联距离后,在加上自身的基线高度.
                    dataBean.y += (addY + Math.min(Math.abs(minY), maxDaolianYDistance / 2));
                }
                //导联间隔
                float distanceDaolian = maxY - minY;
                totalDaolianList.add(tempList.get(i));
                //每个导联增加y的距离,防止重叠.要根据不同导联的高度进行差异增加.并设置最大间隔.
                addY += (Math.min(distanceDaolian, maxDaolianYDistance));
            }
        }
        for (DaolianBean daolianBean : totalDaolianList) {
            for (DataBean dataBean : daolianBean.getPointList()) {
                //x增益算法
                dataBean.x = dataBean.x * xZengyi - leftMargin * (xZengyi - 1);
                //y增益算法
                dataBean.y = dataBean.y * yZengyi;
                pointList.add(dataBean);
            }
        }
        //计算出所有点的最大,最小边界,便于边界拖动处理.
        minXPosition = 0;
        minYPosition = 0;
        if (pointList.size() > 0) {
            minX = pointList.get(0).x;
            minY = pointList.get(0).y;
        }

        maxXPosition = 0;
        maxYPosition = 0;
        if (pointList.size() > 0) {
            maxX = pointList.get(0).x;
            maxY = pointList.get(0).y;
        }

        for (int i = 0; i < pointList.size(); i++) {
            if (pointList.get(i).x < minX) {
                minX = pointList.get(i).x;
                minXPosition = i;
            }
            if (pointList.get(i).y < minY) {
                minY = pointList.get(i).y;
                minYPosition = i;
            }
            if (pointList.get(i).x > maxX) {
                maxX = pointList.get(i).x;
                maxXPosition = i;
            }
            if (pointList.get(i).y > maxY) {
                maxY = pointList.get(i).y;
                maxYPosition = i;
            }

        }

        lastPointList.clear();
        lastPointList.addAll(depCopyData(pointList));
    }

    public ArrayList depCopyDaolian(ArrayList<DaolianBean> srcList) {
        ArrayList<DaolianBean> toList = new ArrayList<>();
        for (DaolianBean daolianBean : srcList) {
            DaolianBean daolianBeanTo = daolianBean.copy();
            toList.add(daolianBeanTo);
        }
        return toList;
    }

    //因为Android 坐标系y轴与心电图的坐标系相反,这里进行一次取反.
    //防止把图画倒.要保证只进行一次取反.
    private void jiaozhengZuobiaoxi() {
        for (DaolianBean daolianBean : originTotalDaolianList) {
            for (DataBean dataBean : daolianBean.getPointList()) {
                dataBean.y *= -1;
            }
        }
    }

    public ArrayList depCopyData(ArrayList<DataBean> srcList) {
        ArrayList<DataBean> toList = new ArrayList<>();
        for (DataBean dataBean : srcList) {
            toList.add(new DataBean(dataBean.x, dataBean.y));
        }
        return toList;
    }

    //还原状态
    private void restore() {
        curScale = 1.0f;
        preScale = 1.0f;
        scaleFousX = 0.0f;
        scaleFousY = 0.0f;
        lastTranslateX = 0;
        lastTranslateY = 0;
        totalRulerTranslateX = 0;
        totalRulerTranlateY = 0;
        isCanMove = false;
        isShowBackGroundLine = true;
        isShowRuler = false;
        xZengyi = 1;
        yZengyi = 1;
        lastPointList.clear();
        lastPointList.addAll(depCopyData(pointList));
        //默认选中所有12个导联
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            list.add(i);
        }
        daolianSelectedList.clear();
        daolianSelectedList.addAll(list);
//        calculateData();
//        invalidate();
    }

    /**
     * sp转换px
     */
    public int sp2px(int spValue) {
        final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}
